const Metro = require('metro');
const outputBundle = require("metro/src/shared/output/bundle")
const _saveAssets = require("@react-native-community/cli/build/commands/bundle/saveAssets")
async function runBuildCustom(config, options) {

  // const bundle = await Metro.runBuild(config, options);

  const sourceMap = options.sourceMap
  const out = options.out;
  const dev = options.dev;
  const sourceMapUrl = options.sourceMapUrl;
  const assetsDest = "bundle-ios";
  const minify = options.minify;
  const metroServer = await Metro.runMetro(config, {
    watch: false
  });

  try {
    const requestOptions = {
      entryFile: options.entry,
      out: options.out,
      platform: platform,
      sourceMapUrl: sourceMap === void 0 ? undefined : sourceMapUrl,
      minify: minify !== undefined ? minify : !options.dev,
      dev: dev,
    }
    process.env.NODE_ENV = dev ? 'development' : 'production';
    const output = requestOptions.output || outputBundle;
    // const metroBundle = await metroServer.build(requestOptions)
    const metroBundle = await output.build(metroServer, requestOptions);
    if (out) {
      const bundleOutput = out.replace(/(\.js)?$/, ".js");
      const sourcemapOutput =
        sourceMap === void 0 ? undefined : out.replace(/(\.js)?$/, ".map");
      const outputOptions = {
        bundleOutput,
        sourcemapOutput,
        dev,
        platform
      }; // eslint-disable-next-line no-console

      await output.save(metroBundle, outputOptions, console.log);
      const outputAssets = await metroServer.getAssets({
        ...requestOptions,
        bundleType: 'todo',
      })
      const dependencyPaths = await metroServer.getOrderedDependencyPaths({
        ...requestOptions
      })
      console.log(dependencyPaths)
      await (0, _saveAssets.default)(outputAssets, platform, assetsDest)
    }
  } catch (error) {
    console.error(error)
  } finally {
    metroServer.end()
  }
}

async function getDependencies(config, options) {
  const metroServer = await Metro.runMetro(config, {
    watch: false
  });
  const requestOptions = {
    entryFile: options.entry,
    out: options.out,
    platform: options.platform,
    sourceMapUrl: options.sourceMap === void 0 ? undefined : options.sourceMapUrl,
    minify: options.minify !== undefined ? options.minify : !options.dev,
    dev: options.dev,
  }
  const dependencyPaths = (await metroServer.getOrderedDependencyPaths({
    ...requestOptions
  })).map(ele => ele.replace(__dirname + '/', ''))
  return dependencyPaths;
}

async function runBuild(config, options) {
  const { build, save, formatName } = outputBundle;
  const { platform, assetsDest } = options;
  options.output = {
    build: async function (packagerClient, requestOptions) {
      const metroBundle = await build(packagerClient, requestOptions)
      const outputAssets = await packagerClient.getAssets({
        ...requestOptions
      })
      await (0, _saveAssets.default)(outputAssets, platform, assetsDest)
      return metroBundle
    },
    save,
    formatName
  }
  await Metro.runBuild(config, options)
}

if (require.main === module) {
  const argv = process.argv;
  const platform = argv[2] || 'ios';
  Metro.loadConfig({
    maxWorkers: 1,
    config: './metro.config.js',
  }).then((config) => {
    const options = {
      entry: 'index.js',
      out: `bundle-${platform}/bundle.js`,
      platform: platform,
      minify: true,
      dev: false,
      sourceMap: false,
      assetsDest: 'bundle-ios'
    }
    // runBuild(config, options);
    getDependencies(config, options)
  });
}


module.exports = { runBuild, getDependencies } 